<?php
/**
 * Copyright 2013 Marek Kaszewski
 *
 * This file is part of the JHUB1 Online Community Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Jhub1_Common\Model;

/**
 * The class belongs to JHUB1 PROJECT
 * The class implements methods for like ISBN-10 check digit calculation validation
 * extended to 32 weight value
 * Marek Kaszewski
 * This is used for validation of the developer and agent unique ID
 * The class generates also random address for virtual devices
 * Deployed in HubsController.php
 */

class KeyGenerator
{

    private $keyGeneratorCharacters = 'xyzcd3ea2bh5iju9vwf4gk6mnp7qrs8t';
    private $weights = array();
    private $randomKeyLength = 10;

    public function __construct()
    {

    }

    public function genKey($length = null)
    {
        if ($length == null) {
            $length = $this->randomKeyLength;
        }
        $key = '';
        $harLength = strlen($this->keyGeneratorCharacters) - 1;
        for ($i = 0; $i < $length; $i++) {
            $key .= $this->keyGeneratorCharacters[rand(0, $harLength)];
        }
        return $key;
    }

    /**
     * method genAddress
     * @param int $length prepared key length
     * @param string $hubName user defined hub's name
     * @return string prepared hub's address
     */
    public function genAddress($length = null, $hubName = null)
    {
        return $this->genKey($length) . "_" . $this->stringPrepare($hubName);
    }

    /**
     * method stringPrepare
     * @param string $str string for preparation
     * @return string prepared string
     * @todo Implement validation/preparation for string which needs to be compliant with the naming convention
     */
    public function stringPrepare($str)
    {
        return $str;
    }

    /**
     * method validateDevKey
     * @param string $devKey developer key generated by dispensing server
     * @return bool depending if the key is validated or not
     * @todo Implement validation/preparation for string which needs to be compliant with the naming convention
     */
    public function validateDevKey($devKey)
    {
        return $this->checkCSum($this->clearString($devKey));
    }

    public function validateAgentKey($agentKey)
    {
        return $this->checkCSum($this->clearString($agentKey));
    }

    private function checkCSum($cleanStr)
    {
        $strLength = strlen($cleanStr);
        if (($strLength == 4) || ($strLength == 6)) {
            return $this->check($strLength, $cleanStr);
        } else {
            return false;
        }
    }

    private function check($length, $str)
    {
        $sum = 0;
        for ($i = 0; $i < $length; $i++) {
            $sum += ($this->weights[$str[$i]] + 1) * ($length - ($i));
        }
        if ($sum % 32 == 0) {
            return true;
        } else {
            return false;
        }
    }

    private function clearString($str)
    {
        $strLength = strlen($str);
        $this->preparePattern();
        $pattern = $this->weights;
        $retStr = "";
        for ($i = 0; $i < $strLength; $i++) {
            if (array_key_exists($str[$i], $pattern)) {
                $retStr .= $str[$i];
            }
        }
        return $retStr;
    }

    private function preparePattern()
    {
        $length = strlen($this->keyGeneratorCharacters);
        $retArr = array();
        for ($i = 0; $i < $length; $i++) {
            $this->weights[$this->keyGeneratorCharacters[$i]] = $i;
        }
        return $retArr;
    }
}

?>
